/**
 * 
 */
package nus.mtech.rate;

import java.util.HashMap;
import java.io.*;

import nus.mtech.constant.Constant;

/**
 * @author Chew Xunmao
 * 
 */

public class RateManager {
	private final static String PROJECT_DIR = System.getProperty("user.dir");
	private static RateManager RateManagerInstance;
	private HashMap<Integer, Rate> mapOfRates = new HashMap<Integer, Rate>();

	public static RateManager getRateManagerInstance() {
		if (RateManagerInstance != null)
			return RateManagerInstance;
		else {
			RateManagerInstance = new RateManager();
			return RateManagerInstance;
		}
	}

	private RateManager() {
		RateManagerInstance = this;
		mapOfRates = new HashMap<Integer, Rate>();
	}

	public void loadRates() {
		try {
			BufferedReader lBufferedReader = new BufferedReader(new FileReader(
					PROJECT_DIR + File.separator + "data" + File.separator + "rates.txt"));
			try {
				String lInputString = lBufferedReader.readLine();
				while (lInputString != null) {
					if (!lInputString.startsWith("//")) {
						lInputString = lInputString.trim();
						String[] lSplittedString = lInputString.split(",");
						createRate(lSplittedString);
					}
					lInputString = lBufferedReader.readLine();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void createRate(String[] splittedStringRate) {

		int lTypeOfRate = Integer.parseInt(splittedStringRate[0]);
		switch (lTypeOfRate) {
		case Constant.DIGITALVOICERATEID:
			createDVRate(splittedStringRate);
			break;
		case Constant.MOBILEVOICERATEID:
			createMVRate(splittedStringRate);
			break;
		case Constant.CABLETVRATEID:
			createCableRate(splittedStringRate);
			break;
		}
	}

	private void createDVRate(String[] rateStr) {
		String lRateName = rateStr[1];
		double lMonthlySubRate = Double.parseDouble(rateStr[2]);
		double lCallTransRate = Double.parseDouble(rateStr[3]);
		double lLocalCallRate = Double.parseDouble(rateStr[4]);
		double lIDDCallRate = Double.parseDouble(rateStr[5]);

		DigitalVoiceRate lNewDVRate = new DigitalVoiceRate(
				Constant.DIGITALVOICERATEID, lRateName, lMonthlySubRate,
				lCallTransRate, lLocalCallRate, lIDDCallRate);
		Rate lNewRate = (Rate) lNewDVRate;

		mapOfRates.put(Constant.DIGITALVOICERATEID, lNewRate);

	}

	private void createMVRate(String[] rateStr) {
		String lRateName = rateStr[1];
		double lMonthlySubRate = Double.parseDouble(rateStr[2]);
		double lDataRate = Double.parseDouble(rateStr[3]);
		double lIDDRate = Double.parseDouble(rateStr[4]);
		double lLocalCallRate = Double.parseDouble(rateStr[5]);
		double lRoamCallRate = Double.parseDouble(rateStr[6]);
		double lRoamingMonthlySubRate = Double.parseDouble(rateStr[7]);

		MobileVoiceRate lNewMVRate = new MobileVoiceRate(
				Constant.MOBILEVOICERATEID, lRateName, lMonthlySubRate,
				lDataRate, lIDDRate, lLocalCallRate, lRoamCallRate,
				lRoamingMonthlySubRate);

		mapOfRates.put(Constant.MOBILEVOICERATEID, (Rate) lNewMVRate);
	}

	private void createCableRate(String[] rateStr) {
		String lRateName = rateStr[1];
		double lMonthlySubRate = Double.parseDouble(rateStr[2]);
		double lChannelRate = Double.parseDouble(rateStr[3]);

		CableRate lNewCableRate = new CableRate(Constant.CABLETVRATEID,
				lRateName, lMonthlySubRate, lChannelRate);

		mapOfRates.put(Constant.CABLETVRATEID, (Rate) lNewCableRate);
	}

	public DigitalVoiceRate getDVRate() {
		if (mapOfRates.containsKey(Constant.DIGITALVOICERATEID))
			return (DigitalVoiceRate) mapOfRates
					.get(Constant.DIGITALVOICERATEID);
		else
			return null;
	}

	public MobileVoiceRate getMVRate() {
		if (mapOfRates.containsKey(Constant.MOBILEVOICERATEID))
			return (MobileVoiceRate) mapOfRates.get(Constant.MOBILEVOICERATEID);
		else
			return null;
	}

	public CableRate getCableRate() {
		if (mapOfRates.containsKey(Constant.CABLETVRATEID))
			return (CableRate) mapOfRates.get(Constant.CABLETVRATEID);
		else
			return null;
	}

}
